<template>
  <div class="home-index clearfix" :class="{'menu-collapse':isCollapse}" v-loading.fullscreen.lock="loading">
    <template v-if="menuData!==null">
      <div class="nav-menu-div">
        <nav-menu :menu-data="menuData"></nav-menu>
      </div>
      <div class="nav-menu-content">
        <div class="nav-menu-header">
          <nav-header :menu-data="menuData" @change-password="toChangePassword"></nav-header>
        </div>
        <div class="nav-menu-router">
          <transition name="el-fade-in">
            <router-view />
          </transition>
        </div>
      </div>
    </template>

    <el-dialog title="修改密码" width="400px" custom-class="sys-dialog" top="calc(50vh - 150px)" :close-on-click-modal="false" :visible.sync="openDialog">
      <div style="height:235px;overflow:auto">
        <update-password v-if="openDialog" :user="user" @update-success="updateSuccess"></update-password>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import {
    mapGetters,
    mapActions
  } from 'vuex';
  import LoginApi from 'services/loginApi';
  import Storage from 'storage';
  import MenuData from 'models/login/menuData';

  import NavMenu from './navMenu';
  import NavHeader from './navHeader';
  import UpdatePassword from './updatePassword';

  export default {
    computed: {
      isCollapse() {
        let menuData = this.menuData;
        if (menuData === null) {
          return false;
        }
        return menuData.isCollapse;
      },

      ...mapGetters(['menus', 'refreshToken', 'user'])
    },

    beforeRouteEnter(to, form, next) {
      let code = to.query.code;
      let user = Storage.getLocal('user');
      if (user === null && code !== undefined) {
        next();
        return;
      }

      let menus = Storage.getSession('menus');
      if (menus === null) {
        LoginApi.getUserData().then(menus => {
          Storage.setSession('menus', menus);
          window.location.reload();
        });
        return;
      }
      next();
    },

    data() {
      return {
        loading: false,
        menuData: null,
        timeout: null,
        openDialog: false
      }
    },

    created() {
      if (this.user === null) {
        let code = this.$route.query.code;
        if (code !== undefined) {
          this.qrcodeLogin(code);
          return;
        }
      }

      this.initData();
    },

    beforeDestroy() {
      this.clearTimeout();
    },

    methods: {
      qrcodeLogin(code) {
        this.loading = true;
        LoginApi.qrcodeLogin(code).then(res => {
          if (res === null) {
            this.$alert('您的微信未绑定账号，请用账号登录绑定微信', '信息', {
              callback: () => {
                this.$router.replace({
                  url: '/login'
                });
              }
            });
            this.loading = false;
            return;
          }

          let systemTime = res.systemTime;
          let nowTime = this.$moment().valueOf();
          let rangeTime = 60 * 1000;
          if (!this.$moment(systemTime).isBetween(nowTime - rangeTime, nowTime + rangeTime, 'second', '[]')) {
            this.$alert('电脑时间与服务器时间不同步，请校对', '提示', {
              callback: () => {
                this.toLoginSystem(res);
              }
            });
          } else {
            this.toLoginSystem(res);
          }
          this.loading = false;
        }).catch(()=>{
          this.loading = false;
        });
      },

      toLoginSystem(res) {
        let authToken = res.auth_token;
        this.setAuthToken(authToken);
        let refreshToken = res.refresh_token;
        this.setRefreshToken({
          data: refreshToken,
          time: this.$moment().valueOf()
        });
        this.setMenus(res.menus);

        let user = res.sessionInfo;
        delete user.userPermissions;
        this.setUser(user);
        window.location.reload();
      },

      setMenuData() {
        this.loading = true;
        return LoginApi.getUserData().then(menus => {
          this.setMenus(menus);
          this.loading = false;
          return menus;
        });
      },

      initData() {
        let menuData = new MenuData(this.menus);
        this.menuData = menuData;
        this.toRefreshToken();
      },

      toRefreshToken() {
        let delayTime;
        let obj = this.refreshToken;
        if (obj === null) {
          delayTime = 20 * 60 * 1000;
        } else {
          let tokenTime = obj.time;
          let nowTime = this.$moment().valueOf();
          if (tokenTime >= nowTime) {
            delayTime = 0;
          } else {
            delayTime = 20 * 60 * 1000 - (nowTime - tokenTime);
            if (delayTime < 0) {
              delayTime = 0;
            }
          }
        }

        this.timeout = setTimeout(() => {
          this.resetToken().then(() => {
            this.timeout = null;
            this.toRefreshToken();
          });
        }, delayTime);
      },

      resetToken() {
        let refreshToken = this.refreshToken.data;
        return LoginApi.getTocken(refreshToken).then(res => {
          let authToken = res.auth_token;
          this.setAuthToken(authToken);
          let refreshToken = res.refresh_token;
          this.setRefreshToken({
            data: refreshToken,
            time: this.$moment().valueOf()
          });
          return res;
        });
      },

      toChangePassword() {
        this.openDialog = true;
      },

      updateSuccess() {
        this.openDialog = false;
      },

      clearTimeout() {
        let timeout = this.timeout;
        if (timeout !== null) {
          window.clearTimeout(timeout);
          this.timeout = null;
        }
      },

      ...mapActions(['setAuthToken', 'setRefreshToken', 'setMenus', 'setUser'])
    },

    components: {
      NavMenu,
      NavHeader,
      UpdatePassword
    }
  }

</script>

<style lang='scss' scoped>
  .home-index {
    height: 100%;

    >div {
      float: left;
      height: 100%;
      overflow: auto;

      &.nav-menu-div {
        width: 200px;
        background: #212529;
      }

      &.nav-menu-content {
        width: calc(100% - 200px);
        overflow: auto;

        .nav-menu-header {
          height: 60px;
        }

        .nav-menu-router {
          position: relative;
          height: calc(100% - 60px);
          overflow: auto;
        }
      }
    }

    &.menu-collapse {
      .nav-menu-div {
        width: 64px;
      }

      .nav-menu-content {
        width: calc(100% - 64px);
      }
    }
  }

  .el-fade-in-enter-active,
  .el-fade-in-leave-active {
    position: absolute;
    top: 0;
    left: 0;
  }

</style>
